
#include "iostream"


#include <vtkAxis.h>
#include <vtkBrush.h>
#include <vtkChartHistogram2D.h>
#include <vtkColor.h>
#include <vtkColorLegend.h>
#include <vtkColorTransferFunction.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkMath.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTable.h>
#include <vtkTextProperty.h>
#include <vtkVector.h>
#include <vtkContextActor.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
//#include <vtkQtView.h>

#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkAxis.h>
#include <vtkBrush.h>
#include <vtkChartHistogram2D.h>
#include <vtkColor.h>
#include <vtkColorLegend.h>
#include <vtkColorTransferFunction.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkMath.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTable.h>
#include <vtkTextProperty.h>
#include <vtkVector.h>
#include <vtkContextActor.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include "vtkPointData.h"
#include "vtkOrientationMarkerWidget.h"
#include "vtkAxesActor.h"
#include "vtkCaptionActor2D.h"

#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>


#include <QApplication>
#include <array>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    // Define colors
    vtkNew<vtkNamedColors> colors;
    vtkColor3d backgroundColor = colors->GetColor3d("SlateGray");
    vtkColor3d titleColor = colors->GetColor3d("Orange");
    vtkColor3d axisTitleColor = colors->GetColor3d("Orange");
    vtkColor3d axisLabelColor = colors->GetColor3d("Beige");
    vtkColor4ub legendBackgroundColor = colors->GetColor4ub("Tomato");

//        // Set up a 2D scene, add an XY chart to it
    int size = 400;

////        vtkNew<vtkContextView> view;
////        view->GetRenderWindow()->SetSize(512, 512);
////        view->GetRenderWindow()->SetWindowName("Histogram2D");

////        view->GetRenderer()->SetBackground(backgroundColor.GetData());


    vtkNew<vtkContextScene> chartScene;
    vtkNew<vtkContextActor> chartActor;
    vtkNew<vtkChartHistogram2D> chart;

    chart->SetAutoSize(false);
    chart->SetSize(vtkRectf(0.0, 0.0, 600, 500));
    chartScene->AddItem(chart);
    chartActor->SetScene(chartScene);

    // Chart Title
    chart->SetTitle("2D Histogram  1");
    chart->GetTitleProperties()->SetFontSize(36);
    chart->GetTitleProperties()->SetColor(titleColor.GetData());

    // Chart Axes
    chart->GetAxis(0)->GetTitleProperties()->SetFontSize(24);
    chart->GetAxis(0)->GetTitleProperties()->SetColor(axisTitleColor.GetData());
    chart->GetAxis(0)->GetLabelProperties()->SetColor(axisLabelColor.GetData());
    chart->GetAxis(0)->GetLabelProperties()->SetFontSize(18);

    chart->GetAxis(1)->GetTitleProperties()->SetFontSize(24);
    chart->GetAxis(1)->GetTitleProperties()->SetColor(
            colors->GetColor3d("orange").GetData());
    chart->GetAxis(1)->GetLabelProperties()->SetColor(
            colors->GetColor3d("beige").GetData());
    chart->GetAxis(1)->GetLabelProperties()->SetFontSize(18);

    // Chart Legend
    dynamic_cast<vtkColorLegend*>(chart->GetLegend())->DrawBorderOn();
    chart->GetLegend()->GetBrush()->SetColor(legendBackgroundColor);


    vtkNew<vtkImageData> data;
    data->SetExtent(0, size - 1, 0, size - 1, 0, 0);
    data->AllocateScalars(VTK_DOUBLE, 1);

    data->SetOrigin(100.0, -100.0, 0.0);
    data->SetSpacing(2.0, 1.0, 1.0);

    double* dPtr = static_cast<double*>(data->GetScalarPointer(0, 0, 0));
    for (int i = 0; i < size; ++i)
    {
        for (int j = 0; j < size; ++j)
        {
            dPtr[i * size + j] =
                    std::sin(vtkMath::RadiansFromDegrees(double(2 * i))) *
                    std::cos(vtkMath::RadiansFromDegrees(double(j)));

            std::cout << dPtr[i * size + j] << " ";
        }
    }

    chart->SetInputData(data);

    vtkNew<vtkColorTransferFunction> transferFunction;
    transferFunction->AddHSVSegment(0.0, 0.0, 1.0, 1.0, 0.3333, 0.3333, 1.0, 1.0);
    transferFunction->AddHSVSegment(0.3333, 0.3333, 1.0, 1.0, 0.6666, 0.6666, 1.0,
                                    1.0);
    transferFunction->AddHSVSegment(0.6666, 0.6666, 1.0, 1.0, 1.0, 0.2, 1.0, 0.3);
    transferFunction->Build();
    chart->SetTransferFunction(transferFunction);





//    vtkNew<vtkCubeSource> cube;
//    vtkNew<vtkPolyDataMapper> cubeMapper;
//    cubeMapper->SetInputConnection(cube->GetOutputPort());
//    vtkNew<vtkActor> actorCube;
//    cube->SetBounds(-1, 1, -1, 1, -1, 1);
//    actorCube->SetMapper(cubeMapper);



    vtkNew<vtkGenericOpenGLRenderWindow> window;
    window->SetMultiSamples(0);
    vtkNew<vtkRenderer> renderer;
    renderer->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());
    window->AddRenderer(renderer);

    vtkCamera* camera = renderer->GetActiveCamera();

//          renderer->ResetCamera();
    camera->SetPosition(0, 10, 10);
    camera->Azimuth(30);
    camera->Elevation(30);

    renderer->AddActor(chartActor);
//    renderer->AddActor(actorCube);

    QWidget *parent = new QWidget();
    parent->resize(800, 800);


    QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
    QVTKOpenGLNativeWidget *widget = new QVTKOpenGLNativeWidget(parent);
    widget->setFixedSize(700, 700);

    widget->setRenderWindow(window);


    // 测试

    std::array<std::string, 3> xyzLabels{{"X", "Y", "Z"}};
    std::array<double, 3> scale{{1.0, 1.0, 1.0}};

    vtkNew<vtkAxesActor> axes111;
    axes111->SetScale(scale[0], scale[1], scale[2]);
    axes111->SetShaftTypeToCylinder();
    axes111->SetXAxisLabelText(xyzLabels[0].c_str());
    axes111->SetYAxisLabelText(xyzLabels[1].c_str());
    axes111->SetZAxisLabelText(xyzLabels[2].c_str());
    axes111->SetCylinderRadius(0.5 * axes111->GetCylinderRadius());
    axes111->SetConeRadius(1.025 * axes111->GetConeRadius());
    axes111->SetSphereRadius(1.5 * axes111->GetSphereRadius());
    vtkTextProperty* tprop = axes111->GetXAxisCaptionActor2D()->GetCaptionTextProperty();
    tprop->ItalicOn();
    tprop->ShadowOn();
    tprop->SetFontFamilyToTimes();
    // Use the same text properties on the other two axes.
    axes111->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->ShallowCopy(tprop);
    axes111->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->ShallowCopy(tprop);

    vtkNew<vtkOrientationMarkerWidget> om2;
    om2->SetOrientationMarker(axes111);
    // Position lower right in the viewport.
//    om2->SetViewport(0.8, 0, 1.0, 0.2);
//    om2->SetViewport(0.5, 0.5, 1.0, 0.2);
    om2->SetViewport(0.0, 0.0, 0.2, 0.2);
    om2->SetInteractor(window->GetInteractor());
//    om2->EnabledOn();
//    om2->SetEnabled(1);
    om2->On();
//    om2->InteractiveOn();

    renderer->AddActor(axes111);


//    window->Render();





    parent->show();

    return a.exec();
}


//
//int main(int, char*[]) {
//
//    std::cout << "hello" << std::endl;
//
//    QWidget *parentWidget = new QWidget();
//    parentWidget->setStyleSheet("background: red;");
////    this->setCentralWidget(parentWidget);
//
////    QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
////    QVTKOpenGLNativeWidget *widget = new QVTKOpenGLNativeWidget(parentWidget);
//////    widget->setRenderWindow(renwin);
//////    renwin->Render();
////    widget->setFixedSize(600, 600);
//
//    parentWidget->show();
//
//    return 0;
//}
